#include "dut/RenderTarget.h"

HRESULT Dut::RenderTarget::Create(ID3D11Device* device, const Desc& desc)
{
	m_Desc = desc;
	OnResize(device);
	return S_OK;

}

void Dut::RenderTarget::Begin(ID3D11DeviceContext* context)
{
	context->RSSetViewports(1, &m_ScreenViewport);

	std::vector<ID3D11RenderTargetView*> rtvs = GetRenderTargetViews();

	context->OMSetRenderTargets(rtvs.size(), &rtvs[0], m_pDepthStencilView.Get());
	for (ID3D11RenderTargetView* rtv : rtvs)
	{
		context->ClearRenderTargetView(rtv, &m_Desc.m_BackgroundColor.x);
	}
	context->ClearDepthStencilView(m_pDepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);

}

void Dut::RenderTarget::UnBind(ID3D11DeviceContext* context)
{
	ID3D11RenderTargetView* nullRTV[] = { nullptr };
	context->OMSetRenderTargets(1, nullRTV, nullptr);
}

void Dut::RenderTarget::OnResize(ID3D11Device* device)
{
	HRESULT hr = S_OK;

	m_Textures.resize(m_Desc.m_NumTextures);
	m_pRenderTargetViews.resize(m_Desc.m_NumTextures);

	/// Create ColorAttachment
	{
		Dut::Texture2D::Desc dutTexDesc;
		dutTexDesc.m_Width = m_Desc.m_Width;
		dutTexDesc.m_Height = m_Desc.m_Height;

		dutTexDesc.m_BindFlag =  D3D11_BIND_RENDER_TARGET;


		D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
		rtvDesc.Format = m_Desc.m_Format;
		rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
		rtvDesc.Texture2D.MipSlice = 0;


		for (int i = 0; i < m_Desc.m_NumTextures; i++)
		{
			Dut::Texture2D& tex = m_Textures[i];
			ComPtr<ID3D11RenderTargetView>& rtv = m_pRenderTargetViews[i];

			HR(tex.Create(device, dutTexDesc));
			HR(device->CreateRenderTargetView(tex.m_Texture.Get(), &rtvDesc, rtv.ReleaseAndGetAddressOf()));

		}

	}

	// Create StentilDepthBuffer Texture And ShaderResources
	{

		Dut::Texture2D::Desc dpTexDesc;
		dpTexDesc.m_Width = m_Desc.m_Width;
		dpTexDesc.m_Height = m_Desc.m_Height;
		dpTexDesc.m_Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
		//dpTexDesc.m_SrvFormat = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
		dpTexDesc.m_BindFlag = D3D11_BIND_DEPTH_STENCIL;
		dpTexDesc.m_CreateSrv = false;

		m_depthStencilTexture.Create(device, dpTexDesc);

	}


	{
		D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
		ZeroMemory(&dsvDesc, sizeof(dsvDesc));

		dsvDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
		dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
		dsvDesc.Texture2D.MipSlice = 0;

		device->CreateDepthStencilView(m_depthStencilTexture.m_Texture.Get(), &dsvDesc, m_pDepthStencilView.ReleaseAndGetAddressOf());

	}




	m_ScreenViewport.Width = static_cast<float>(m_Desc.m_Width);
	m_ScreenViewport.Height = static_cast<float>(m_Desc.m_Height);
	m_ScreenViewport.MinDepth = 0.0f;
	m_ScreenViewport.MaxDepth = 1.0f;
	m_ScreenViewport.TopLeftX = 0;
	m_ScreenViewport.TopLeftY = 0;

}

std::vector<ID3D11RenderTargetView*> Dut::RenderTarget::GetRenderTargetViews()
{
	std::vector<ID3D11RenderTargetView*> res;

	for (auto rtv : m_pRenderTargetViews)
	{
		res.push_back(rtv.Get());
	}

	return res;
}
